OneNote Defects

November 15, 2022

Last updated on September 7, 2026

These are support questions posted to:

 

 

 

 

I'm writing to request an enhancement to the OneNote Interop API — specifically, the ability to support merged table cells in the XML schema used by the UpdatePageContent method.

 

With the recent addition of cell merging in OneNote for Microsoft 365, this feature has become essential for creating more flexible and visually organized tables. However, the current Interop API does not reflect this capability, and there is no documented support for attributes like colspan or rowspan in the XML schema.

 

Why this matters:

  • Developers cannot programmatically replicate merged cells created in the OneNote UI. I am the author of the OneMore add-in (github.com/stevencohn/OneMore).
  • Automation and content generation tools are limited in their ability to produce rich, structured layouts.
  • Imported tables with merged cells are automatically flattened, leading to data loss or formatting issues.

 

Suggested enhancement:

  • Extend the OneNote XML schema to include support for merged cells, possibly via new attributes or nested structures within <TD> elements.
  • Update the documentation and SDK to reflect these changes and provide examples.

 

This feature would greatly improve the fidelity of programmatic content creation and align the API with the capabilities of the OneNote client.

 

Thank you for considering this request. I’d be happy to provide use cases or collaborate on testing if needed.

 

 

 

📓

OneNote Interop API NavigateToUrl fails if called again too quickly

Aug 18, 2026 @ Feedback Portal

 

Aug 17, 2026 @ Tech Community

Nov 15, 2022 @ Q&A

 

C# with .NET Framework 4.8, OneNote 16.0.15726.20188 64-bit

 

Using the Interop API, IApplication.NavigateToUrl(pageURL)

 

Invoke once with a valid page URL, it succeeds

 

Invoke again (within about two seconds) with a different valid page URL, it fails with COMException, HResult: 0x80042014 "The object does not exist"

 

However, if you wait at least about three seconds in between calls, then it will always succeed.

 

It doesn't matter whether the second page is in the same notebook or a different notebook. All notebooks tested here are synced to the cloud.

 

It appears that NavigateToUrl causes the notebook to sync, because the OneNote notebook panel shows the sync glyph on top of the notebook icon and that is perhaps blocking subsequent interop APIs until completed?

 

The IApplication instance is instantiated and disposed in a "using" block for each call

 

See also

Can you update the contents of a page reliably with PATCH ../notes/pages/{id}/content

April 2, 2022

Jason Chapman

 

 

 

 

C# with .NET Framework 4.8, OneNote 16.0.15726.20188 64-bit

 

Using the Interop API, IApplication.UpdatePageContent(xml, lastModTime, XMLSchema.xs2013, true)

 

Given a page with one Outline and two OE paragraphs where each OE paragraph was contributed by different authors on different dates.

 

If any change is made to the Outline, such as appending a new OE, without modifying the existing OEs, then when the page is saved using UpdatePageContent, the lastModifiedTime attribute of all descendants of that Outline are updated to the current time. This results in losing information regarding when a particular author applied their changes.

 

The expectation is that the EditedByAttributes (per 0336.OneNoteApplication_2013.xsd) of an OE should be preserved unless that OE's content has changed.

 

Users who share notebooks often rely on the EditedByAttributes (who and when) for individual parts of a page to track independent changes. The current behavior loses that auditing capability.

 

Note that this usage is based on  https://learn.microsoft.com/en-us/office/client-developer/onenote/application-interface-onenote#updatepagecontent-method which explains:

 

  • You must include page-level objects in the UpdatePageContent call
  • The dateExpectedLastModified is nothing more than a pessimistic locking type of safe-guard and is not considered in any regard in relation to the lastModifiedTime attribute

 

 

 

📓

OneNote Interop API UpdatePageContent breaks Spell Checking

Aug 18, 2026 @ Feedback Portal

 

Aug 17, 2026 @ Tech Community

Dec 2, 2023 @ Q&A

 

C# with .NET Framework 4.8, OneNote 16.0.16924.20150 64-bit

 

Using the interop API, IApplication.UpdatePageContent(xml, lastModTime, XMLSchema.xs2013, true)

 

Given a page with an OE paragraph, where the user selects a run of text, not including the end of the text, and the text contains spelling errors before, within, and after the selection range.

 

When the proofing language is changed for the selected range, then the spelling errors after that range will no longer be highlighted as errors.

 

Here is an example text run, before modification, with a selection range. Notice the word "benoyd" is misspelled and would be highlighted by OneNote.

 

  <one:OE alignment="left" quickStyleIndex="1" selected="partial">

    <one:T><![CDATA[To ]]></one:T>

    <one:T selected="all"><![CDATA[infinity]]></one:T>

    <one:T><![CDATA[ and benoyd...]]></one:T>

  </one:OE>

 

And after modification to change the language of the selected range:

 

  <one:OE alignment="left" quickStyleIndex="1">

    <one:T><![CDATA[<span

lang=en-US>To </span><span lang=yo>infinity</span><span lang=en-US> and benoyd...</span>]]></one:T>

  </one:OE>

 

But the word "benoyd" is no longer highlighted as misspelled. The user can manually iterate through the text by interactively clicking the Review/Spelling button, causing OneNote to highlight the misspellings.

 

Alternatively, if the user changes the proofing language of the selected range interactively using the Proofing Language panel, it results in exactly the same XML structure generated by OneNote natively, but OneNote retains the misspelling indicators.

 

Making exactly the same changes to the XML using the UpdatePageContent API should result in the same behavior as using the UI.

 

 

 

📓

OneNote Interop API targets wrong window instance

Aug 18, 2026 @ Feedback Portal

 

Aug 17, 2026 @ Tech Community

Nov 23, 2024 @ Q&A

 

C# with .NET Framework 4.8, Microsoft® OneNote® 2021 MSO (Version 2410 Build 16.0.18129.20100) 64-bit

 

Open up two OneNote windows viewing the same page. From the second window, invoke an add-in command that uses the managed Interop API.

 

Any queries or updates made by the API will target the first OneNote window instance, even while the second window instance is active and has focus.

 

However, if the content of the page is manually modified from the second [active] window instance, then and only then will the API call target and update the page in the second window.

 

Expectation is that the updated content will be visible immediately in the active OneNote window instance.

 

--

 

This has happened in all version of OneNote, all build numbers that I've tried, since early releases of OneNote 2021; it is a systemic issue in the Interop API. Let me give a more clear example.

 

  1. Open page (A) in window (1) and set the cursor on paragraph (a)
  2. Open page (A) in window (2) and set the cursor on paragraph (b) -- window (2) is active
  3. GetPageContent(CurrentPageId) returns XML showing that the cursor is on paragraph (a)
  4. Any add-in logic that depends on the text cursor location (selected=all) or selection range will update paragraph (a), not paragraph (b).

 

This is unexpected from the end user's perspective, and from my perspective as a developer.

 

You can reverse that, continuing from step 4 above:

 

  1. Make any change in window (2) and set the cursor on paragraph (b)
  2. Click on window (1) to make it active and set the cursor on paragraph (a)
  3. GetPageContent will return XML showing the cursor on paragraph (b)

 

Again, wrong context. This is a focus problem that add-ins should not be responsible for solving in my opinion.

 

 

📓

OneNote Interop API: Local paragraph style attributes not retained after UpdatePageContent

Aug 18, 2026 @ Feedback Portal

 

Aug 17, 2026 @ Tech Community

Aug 15, 2026 @ Q&A

 

Description: When using the OneNote COM Interop API, I’ve observed that certain local paragraph style attributes are not preserved after calling UpdatePageContent. This occurs when the local style contains only fontfamily and fontsize values that match the properties already defined in the referenced QuickStyleDef.

 

The sequence is:

 

  • A page contains a QuickStyleDef with specific font properties, including a color.
  • A paragraph references this QuickStyleDef and also includes a local style attribute that repeats only the fontfamily and fontsize.
  • The page XML is submitted through UpdatePageContent.
  • When retrieving the page again using GetPageContent, the local style attribute is no longer present on that paragraph. Other elements and attributes remain unchanged.

 

Because the local style is no longer present, the paragraph uses only the QuickStyleDef’s formatting.

 

What I’m trying to understand: Is this behavior expected when a local style duplicates properties already defined in the QuickStyleDef? Or should the Interop API retain the local style attribute exactly as provided in the XML passed to UpdatePageContent?

 

Environment:

  • C# / .NET Framework 4.8
  • OneNote for Microsoft 365
  • Interop API: GetPageContent and UpdatePageContent
  • XMLSchema.xs2013

 

I can provide a minimal XML example if needed, but I’ve omitted it here to keep the post concise.

 

 

This is the original defect text I tried to submit, but the Microsoft Q&A site kept rejecting it as violating their policy!

 

Summary: When using the OneNote COM Interop API to roundtrip page XML, local paragraph style attributes are removed if they match the font properties already defined in the referenced QuickStyleDef. After this normalization, the paragraph inherits the QuickStyleDef’s color, which can cause text to become unreadable if the QuickStyleDef uses a color that is not visible against the page background.

 

Environment: C# / .NET Framework 4.8 OneNote for Microsoft 365 IApplication.UpdatePageContent / IApplication.GetPageContent XMLSchema.xs2013

 

Description: If a page contains a QuickStyleDef with a specific fontColor (for example, #FFFFFF) and a paragraph that references this QuickStyleDef also includes a local style attribute that duplicates only the font family and size (but does not specify a color), the following behavior occurs: The page XML is retrieved using GetPageContent. The same XML is sent back to OneNote using UpdatePageContent, either when creating a new page or updating an existing one. After the update, retrieving the page again shows that the local style attribute has been removed from the affected one:OE elements. Because the local style no longer provides a font color override, the paragraph inherits the QuickStyleDef’s color. If that color is not visible (e.g., white text on a white background), the paragraph appears blank even though the text is still present.

 

Reproduction steps: Create a new page using CreateNewPage. Provide XML containing: A QuickStyleDef such as:

 

<one:QuickStyleDef index="1" name="p" fontColor="#FFFFFF" font="Calibri" fontSize="11.0" />

 

An Outline with an OE referencing this QuickStyleDef and containing a local style attribute that duplicates the font properties:

 

<one:OE quickStyleIndex="1" style="font-family:Calibri;font-size:11.0pt">

  <one:T>Example text</one:T>

</one:OE>

 

Call UpdatePageContent with the XML. Retrieve the page again using GetPageContent.

 

Observed behavior: The returned XML no longer contains the style attribute on the OE element. All other attributes and elements are preserved. The paragraph now renders using the QuickStyleDef’s color.

 

Expected behavior: Local style attributes that are present in the XML passed to UpdatePageContent should remain in the stored page XML, even if they duplicate properties from the QuickStyleDef, so that the effective formatting remains unchanged. Impact: Any tool that copies or rewrites page content through the Interop API may encounter unexpected formatting changes when OneNote normalizes style attributes. If the QuickStyleDef uses a color that is not visible, paragraphs may appear blank after roundtripping through the API.

 

Additional note: This behavior can also occur when updating an Outline that contains multiple OE elements. If one OE is modified and the entire Outline is resent, sibling OEs may also have their local style attributes normalized in the same way. If you want, I can also prepare a shorter version optimized for Q&A’s character limits or a developerfocused version aimed at Office engineering.

 

 

 

Description:

With a diagnostic PowerShell 5 script, using the OneNote desktop COM Interop API, I've noticed the Page-level XML lastModifiedTime attribute always returns the current time, regardless of when the page was actually last modified.

 

The GetHierarchy call, with the hsPage scope (4) parameter, does return the correct modification time of the page.

 

Expectation:

I imagine the original intent was to feed the page-level lastModifiedTime into the UpdatePageContent's expectedLastModifiedTime parameter. But I would expect this parameter to want the actual last-modified time, not the last-read time.

 

Was this an attempt at optimistic locking using the timestamp to resolve concurrent write attempt from multiple processes? Windows is typically single-user, but this could help prevent overwrites from service processes. I guess.

 

This should at least be documented if that's the intent. If not, then the page-level lastModifiedTime attribute should be the same as the hierarchy's page element lastModifiedTime value.

 

Environment:

  • C# / .NET Framework 4.8
  • OneNote  - all versions since 2021
  • Interop API: GetPageContent and GetHierarchy
  • XMLSchema.xs2013
  • No add-ins were installed during this test.

 

 

 

When a page's live editing selection spans three or more paragraphs and one of the interior paragraphs is a MathML equation (a one:T whose CDATA is entirely an <!--[if mathML]>..<![endif]--> comment), any subsequent UpdatePageContent call that touches only the other selected paragraphs causes OneNote to prepend a stray formatting artifact — a span/br pair carrying default run properties — directly into the equation's own CDATA, immediately before the MathML comment. The equation paragraph's one:OE also loses its original style attribute (the one recording the equation's font/size) and gains an unrelated lang="en-US" attribute. This happens even though the submitted XML never referenced or modified the equation paragraph at all.

 

Reproduction

Starting page content (five sibling one:OE under one outline — plain text, an empty separator paragraph, the equation, another empty separator, plain text):

 

<one:OE alignment="left" quickStyleIndex="1">

  <one:T><![CDATA[normal text]]></one:T>

</one:OE>

<one:OE alignment="left" quickStyleIndex="1">

  <one:T><![CDATA[]]></one:T>

</one:OE>

<one:OE alignment="left" quickStyleIndex="1" style="font-family:'Cambria Math';font-size:11.5pt">

  <one:T><![CDATA[<!--[if mathML]><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><msup><mi>a</mi><mn>2</mn></msup><mo>+</mo><msup><mi>b</mi><mn>2</mn></msup><mo>=</mo><msup><mi>c</mi><mn>2</mn></msup></math><![endif]-->]]></one:T>

</one:OE>

<one:OE alignment="left" quickStyleIndex="1">

  <one:T><![CDATA[]]></one:T>

</one:OE>

<one:OE alignment="left" quickStyleIndex="1">

  <one:T><![CDATA[normal text]]></one:T>

</one:OE>

 

Steps:

  1. In the UI, place the selection starting before the first "normal text" paragraph and ending after the last one, so the selection spans all five paragraphs including the equation.
  2. Apply any formatting command that edits only the two "normal text" one:T runs (e.g. a font/color change, or a case transform such as UPPERCASE). The calling add-in's outgoing XML — verified independently, see Evidence below — sets a style attribute on the two text one:OE elements and leaves the equation's one:OE/one:T byte-for-byte untouched.
  3. Call IApplication.UpdatePageContent(pageId, xml) with that XML.
  4. Call IApplication.GetPageContent(pageId, out xml) again and inspect the result.

 

Resulting content:

 

<one:OE alignment="left" quickStyleIndex="1" style="font-family:'Lucida Console';font-size:9.5pt;color:black">

  <one:T><![CDATA[normal text]]></one:T>

</one:OE>

<one:OE alignment="left" quickStyleIndex="1">

  <one:T><![CDATA[]]></one:T>

</one:OE>

<one:OE alignment="left" quickStyleIndex="1" lang="en-US">

  <one:T><![CDATA[<span style='font-family:Calibri' lang=en-US><br />

</span><!--[if mathML]><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><msup><mi>a</mi><mn>2</mn></msup><mo>+</mo><msup><mi>b</mi><mn>2</mn></msup><mo>=</mo><msup><mi>c</mi><mn>2</mn></msup></math><![endif]-->]]></one:T>

</one:OE>

<one:OE alignment="left" quickStyleIndex="1">

  <one:T><![CDATA[]]></one:T>

</one:OE>

<one:OE alignment="left" quickStyleIndex="1" style="font-family:'Lucida Console';font-size:9.5pt;color:black">

  <one:T><![CDATA[normal text]]></one:T>

</one:OE>

 

The two "normal text" paragraphs picked up the intended formatting correctly — that part is expected and correct. The equation paragraph, which the caller never touched, is the problem:

 

  • Its one:T CDATA now begins with <span style='font-family:Calibri' lang=en-US><br /> followed by a newline and </span>, prefixed before the <!--[if mathML]> comment.
  • Its one:OE lost its original style="font-family:'Cambria Math';font-size:11.5pt" attribute and gained lang="en-US" instead.

 

The neighboring empty separator paragraphs are unaffected; only the equation paragraph is corrupted.

 

Expected behavior

UpdatePageContent should only apply the deltas present in the submitted XML. A paragraph that is byte-identical between the pre-edit GetPageContent snapshot and the submitted update XML must be persisted unchanged, regardless of its content type and regardless of where it falls relative to the edited selection range.

 

Actual behavior

OneNote appears to synthesize a soft-break/default-run-properties artifact as part of reconciling a multi-paragraph selection edit, and misattributes that artifact to the equation paragraph's CDATA and OE attributes instead of discarding it or attaching it to a plain-text paragraph. The result is that a MathML equation is silently mutated by an edit operation that never referenced it, and the equation's original paragraph-level style is lost.

 

Evidence this originates inside OneNote, not the calling application

The add-in used to observe this logs the exact XML string immediately before it is passed to UpdatePageContent. That logged XML does not contain the injected span/br fragment anywhere — the equation paragraph is submitted byte-for-byte identical to how it was read. The corruption is only observable in the next GetPageContent call, after UpdatePageContent has returned. This rules out any client-side XML construction bug as the source and isolates the defect to OneNote's own processing of the update (either within UpdatePageContent itself or in how the live editor reconciles the document surface against it).

 

Note: this was verified through the add-in's own instrumentation rather than a minimal bare-COM console repro; a reduced repro using only Microsoft.Office.Interop.OneNote (no add-in) would be worth building to confirm before/if this is escalated, but the observed pattern (clean outgoing XML → polluted result on read-back) is consistent across repeated trials with both a case-transform command and a font-color command.

 

Impact

Any third-party or first-party code that edits page content via the Interop API risks silently corrupting MathML equations whenever a user's edit selection happens to span across one — even if that code has never heard of MathML and never touches the equation's XML. This is exactly the scenario OneNote Gem's "Equation Shield" and OneMore's own MathML-safety work (tracked at stevencohn/OneMore issue 1425) are designed to guard against on the client side, but client-side guarding cannot prevent OneNote's own engine from injecting this artifact after the client's clean XML has already been submitted and accepted.

 

Suggested workaround (none found)

No client-side workaround was found: pre-save "purity" sanitization of the equation's CDATA runs before the call to UpdatePageContent, which is necessarily too early to strip an artifact that OneNote injects only after processing the update. Avoiding selections that span a MathML paragraph is the only mitigation identified so far, which is not practical for general-purpose text-formatting commands.

 

Environment:

  • C# / .NET Framework 4.8
  • OneNote  - all versions since 2021
  • Interop API: GetPageContent and UpdatePageContent
  • XMLSchema.xs2013
  • No add-ins were installed during this test.

 

 

 

 

#omwiki #omdeveloper #omtechnote

 

© 2020 Steven M Cohn. All rights reserved.

Please consider a sponsorship or one-time donation to support ongoing development

 

Created with OneNote.